<?php

namespace App\Traits;

use Closure;
use Illuminate\Database\Eloquent\Builder;

trait SpliceQuery
{
    /**
     * 将格式化的query条件拼接成Eloquent ORM的查询条件
     */
    public function spliceQueryConditions(Builder &$query, array $format_conditionis)
    {
        $this->query = $query;
        foreach ($format_conditionis as $condition) {
            if (empty($condition[1])) $this->thisAbort();

            if (stristr($condition[1], 'select')) $this->selects($condition);
            if (stristr($condition[1], 'where')) $this->wheres($condition);
            if (stristr($condition[1], 'leftjoin')) $this->joins($condition);
            if (stristr($condition[1], 'with')) $this->withs($condition);
        }
    }
    /**
     * 派发where相关条件查询
     */
    private function wheres($condition)
    {
        switch ($condition[1]) {
            case 'where':
                $this->spliceWhere($condition);
                break;
            case 'whereIn':
                $this->spliceWhereIn($condition);
                break;
            case 'whereBetween':
                $this->spliceWhereBetween($condition['main']);
                break;
        }
    }
    //where相关查询
    private function spliceWhere($condition)
    {
        if (empty($condition[2])) $this->thisAbort();

        if (is_array($condition[2])) {
            if (empty($condition[2][0]) || empty($condition[2][1])) $this->thisAbort();

            $this->query->where($condition[0], $condition[2][0] ?? '=', $condition[2][1] ?? '');
        } elseif ($condition[2] instanceof Closure) {
            $this->query->where($condition[2]);
        } else {
            if (empty($condition[2])) $this->thisAbort();

            $this->query->where($condition[0], $condition[2]);
        }
    }
    private function spliceWhereIn($condition)
    {
        if (empty($condition[2])) $this->thisAbort();
        $this->query->whereIn($condition[0], $condition[2]);
    }
    private function spliceWhereBetween($condition)
    {
    }

    private function joins($condition)
    {
        switch ($condition[1]) {
            case 'leftJoin':
                $this->spliceLeftjoin($condition);
                break;
            case 'rightJoin':
                $this->spliceRightJoin($condition);
                break;
            case 'join':
                $this->spliceJoin($condition);
                break;
        }
    }
    private function spliceLeftJoin($condition)
    {
        if (empty($condition[0]) || empty($condition[2][0]) || empty($condition[2][1])) $this->thisAbort();

        $this->query->leftJoin($condition[0], $condition[2][0], '=', $condition[2][1]);
    }
    private function spliceRightJoin($condition)
    {
    }
    private function spliceJoin($condition)
    {
    }

    private function withs($condition)
    {
        if (empty($condition[2])) $this->thisAbort();
        if (count($condition[2]) == 1) {
            $this->query->with($condition[2]);
        } elseif (count($condition[2]) == 2) {
            foreach ($condition[2] as $table => $func) {
                $this->query->with([$table => $func]);
            }
        }
    }

    private function selects($condition)
    {
        if (empty($condition[2])) $this->thisAbort();

        call_user_func_array(array($this->query, 'select'), $condition[2]);
    }


    private function thisAbort()
    {
        abort(500, '参数错误');
    }
}
